package cn.eu.common.query.annotation;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.github.yulichang.wrapper.JoinAbstractLambdaWrapper;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.*;
import java.util.Collection;
import java.util.Objects;

/**
 * @author zhaoeryu
 * @since 2023/6/3
 */
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Query {

    Type type() default Type.EQ;

    String[] field() default {};

    /**
     * 查询方式
     */
    @Slf4j
    enum Type {
        APPLY,
        // =
        EQ,
        // >
        GT,
        // >=
        GE,
        // <
        LT,
        // <=
        LE,
        // "%?%"
        LIKE,
        // "%?"
        LEFT_LIKE,
        // "?%"
        RIGHT_LIKE,
        // in
        IN,
        // not in
        NOT_IN,
        // between
        BETWEEN,
        // <>
        NE,
        ;

        public void setCondition(JoinAbstractLambdaWrapper<?, ?> wrapper, String leftColumn, Object value) {
            if(Objects.isNull(value) || StrUtil.isBlankIfStr(value)) return;
            switch (this) {
                case APPLY:
                    wrapper.apply(StrUtil.format("{} = {}", leftColumn, StrUtil.toStringOrNull(value)));
                    break;
                case EQ:
                    wrapper.eq(leftColumn, value);
                    break;
                case GT:
                    wrapper.gt(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case GE:
                    wrapper.ge(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case LT:
                    wrapper.lt(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case LE:
                    wrapper.le(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case NE:
                    wrapper.ne(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case LIKE:
                    wrapper.like(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case LEFT_LIKE:
                    wrapper.likeLeft(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case RIGHT_LIKE:
                    wrapper.likeRight(leftColumn, StrUtil.toStringOrNull(value));
                    break;
                case IN:
                    if(value instanceof CharSequence) {
                        wrapper.in(leftColumn, StrUtil.split((CharSequence) value, ","));
                    } else {
                        wrapper.in(leftColumn, value);
                    }
                    break;
                case NOT_IN:
                    if(value instanceof CharSequence) {
                        wrapper.notIn(leftColumn, StrUtil.split((CharSequence) value, ","));
                    } else {
                        wrapper.notIn(leftColumn, value);
                    }
                    break;
                case BETWEEN:
                    Object[] values = null;
                    if(ArrayUtil.isArray(value)) {
                        values = ((Object[]) value);
                    } else if(value instanceof Collection) {
                        values = ((Collection<?>) value).toArray();
                    }
                    // 取出第一个和第二个值，如果不是两个值，就不处理，如果是两个值，并且不为空，就处理
                    if (ArrayUtil.isNotEmpty(values)) {
                        if (values.length == 2 && values[0] != null && values[1] != null) {
                            wrapper.between(leftColumn, values[0], values[1]);
                        } else {
                            log.warn("BETWEEN条件需要两个值，当前值为：{}", value);
                        }
                    }
                    break;
                default:
                    log.warn("未支持的查询类型：{}", this.name());
                    break;
            }
        }
    }
}
